Skip to content

feat(labrinth): rework v3 side types to a single environment field #3701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

AlexTMjugador
Copy link
Member

@AlexTMjugador AlexTMjugador commented May 24, 2025

Side types (also known as environment types) are Labrinth's way of representing where a version of a project can be installed (on the client, an integrated singleplayer server, a dedicated multiplayer server, or a combination of these) and where and how much functionality provides to the user (more on the client, more on the server, or both).

Historically, coming up with the right representation for that concept has been a challenging problem. Because projects can integrate into very diverse parts of the Minecraft game with differing levels of functionality, devising a single abstraction that handles all edge cases has proven difficult: the current client_side/server_side (in the v2 routes) and server_only/singleplayer/client_and_server/client_only (in the v3 routes) fields introduce issues for both developers and users. One one hand, developers struggle to write code that makes the right assumptions, e.g. when determining what mods to install on which side for modpacks. On the other hand, users can find it unclear which side type to select when authoring a project, increasing the workload for content moderators and leading to a worse user experience.

This PR lays the foundation for a new approach to side types, centered around a single environment loader enum field for project versions in the v3 routes. The design around this field reflects a consensus reached through an RFC shared in the contributors channel of our Discord server, along with internal planning and discussions (see MOD-275, MOD-48). The values for that field are:

  • client_and_server: must be installed on both the client and on a (possibly singleplayer) server.
  • client_only: must be installed only on the client.
  • client_only_server_optional: must be installed on the client, but may be installed on a (possibly singleplayer) server. The UI should highlight this as a mostly-client mod.
  • singleplayer_only: Must be installed only on the integrated singleplayer server. Displayed as a server mod for singleplayer exclusively.
  • server_only: must be installed only on a (possibly integrated) server.
  • server_only_client_optional: must be installed on a (possibly singleplayer) server, but may be installed on the client. Displayed as a singleplayer-compatible server mod.
  • dedicated_server_only: must be installed only on a dedicated multiplayer server (not the integrated singleplayer server). Displayed as a server mod for multiplayer exclusively.
  • client_or_server: can be installed on both client and server, with no strong preference for either. Displayed as both a client and server mod.
  • client_or_server_prefers_both: can be installed on both client and server, with a preference for being installed on both. Displayed as a client and server mod.
  • unknown: fallback value for when the environment is not known yet.

For now, only the v3 routes, which are considered experimental and not subject to versioning guarantees, have had their fields changed. When a project is manipulated using v2 routes, the environment loader field is transparently converted to boolean client_side and server_side fields, which entails some loss, since environment can express more information. Similarly, the automatic translation done in the DB migration proposed in this PR between the server_only, singleplayer, client_and_server, and client_only fields to the new environment field may also change the semantics of how project sides are categorized.

TODO

  • Test DB migration with realistic data from the staging environment.
  • Review Labrinth integration tests, make sure they do not introduce any regressions.
  • End-to-end testing of proper side type handling during project and version creation, edition, retrieval, and search.

@AlexTMjugador AlexTMjugador added enhancement New feature or request backend Relates to Modrinth Backend or API labels May 24, 2025
@AlexTMjugador AlexTMjugador force-pushed the alex/environment-loader-field branch from 749d512 to 859e0bf Compare May 24, 2025 21:03
@AlexTMjugador AlexTMjugador marked this pull request as ready for review May 25, 2025 14:22
@AlexTMjugador AlexTMjugador requested a review from Copilot May 25, 2025 14:23
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new approach to representing side types by replacing multiple legacy boolean fields with a single "environment" field in v3 routes. Key changes include updates to test cases to use the new field, updates in conversion functions to map legacy side types to the new environment values, and a migration script to convert existing data.

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apps/labrinth/tests/search.rs Updated test queries to use the new "environment" field.
apps/labrinth/tests/loader_fields.rs Refactored JSON patches to remove legacy fields.
apps/labrinth/tests/common/search.rs Updated JSON modifications for side type filtering.
apps/labrinth/tests/common/api_v3/request_data.rs Adjusted test data to use "environment" values.
apps/labrinth/src/search/indexing/mod.rs Updated indexing configuration for the new field.
apps/labrinth/src/search/indexing/local_import.rs Updated function call for converting side types.
apps/labrinth/src/routes/v2_reroute.rs Renamed and refactored conversion functions for side types.
apps/labrinth/src/routes/v2/version_creation.rs Updated field defaults to use "unknown" for missing data.
apps/labrinth/src/routes/v2/projects.rs Updated project editing to use the new conversion scheme.
apps/labrinth/src/routes/v2/project_creation.rs Updated project creation conversion for side types.
apps/labrinth/src/queue/moderation.rs Updated moderation checks to reference the new field.
apps/labrinth/src/models/v2/search.rs Refactored loader field extraction to use string values.
apps/labrinth/src/models/v2/projects.rs Updated extraction of side types from version fields.
apps/labrinth/migrations/20250523174544_project-versions-environments.sql Added migration for converting legacy side type fields.

This field is meant to be able to represent the existing v2 side type
information and beyond, in a way that may also be slightly easier to
comprehend.
@AlexTMjugador AlexTMjugador force-pushed the alex/environment-loader-field branch from fc730a9 to fa04de9 Compare May 25, 2025 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Relates to Modrinth Backend or API enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

1 participant